package cd826dong.cloud.oauth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import java.util.Arrays;

@Configuration
public class OAuthConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;
    @Autowired
    private TokenEnhancer jwtTokenEnhancer;



    /*认证服务的框架搭建好之后就可以创建OAuth客户端的管理了。
    开发过与OAuth集成应用的读者都知道， 当需要和第三方认证集成时
    通常要提供一个ClientID（或AppID） 和ClientSecret（或AppSecret）
    用来进行认证。 对于我们所要搭建的OAuth认证服务器也一样， 只有
    认证后的应用才可以使用所提供的用户认证服务。 具体实现方式就是
    需要扩展Spring的AuthorizationServerConfigurerAdapter， 并覆写其中的
    configure（） 方法。 具体代码如下：*/
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("springclouddemo")
                .secret("scdsecrete")
                .authorizedGrantTypes("refresh_token", "password", "client_credentials")
                .scopes("webclient", "mobileclient");
    }

    /* 在上面的代码中我们使用内存方式直接注册了一个ClientID为
     springclouddemo， scdsecrete， 并且授权该客户端可以
     使用refresh_token、 password、 client_credentials等的客户端授权方
     式。*/
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // 设置用户及认证的实现
//        endpoints.authenticationManager(authenticationManager)
//                .userDetailsService(userDetailsService);

        // 增加一个令牌增强配置
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(this.jwtTokenEnhancer, this.jwtAccessTokenConverter));
        // 定义如何将OAuth生成的访问令牌转换成JWT令牌
        endpoints.tokenStore(this.tokenStore)
                .accessTokenConverter(this.jwtAccessTokenConverter)
                .tokenEnhancer(tokenEnhancerChain)
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }


}
